namespace ScrumSprintMonitor.Modules.WorkItemMonitor.ViewModels
{
	#region #using Directives

	using System.Windows;
	using System.Windows.Controls;

	using Infrastructure.Configuration;

	using Microsoft.Practices.ServiceLocation;

	using UI.Wpf.ViewModels;

	#endregion

	public class SprintTitleViewModel : SprintViewModelBase,
	                                    ISprintTitleViewModel
	{
		static SprintTitleViewModel()
		{
			var dependsOn = Register<SprintTitleViewModel>();

			dependsOn.Call(me => me.EnsureConfigurationIsPresent()).OnChanged(me => me.ReportableData);
			dependsOn.Call(me => me.OnPropertyChanged("CurrentSprintName")).OnChanged(me => me.ReportableData.CurrentSprint.Name);
			dependsOn.Call(me => me.OnPropertyChanged("SprintPercentageCovered")).OnChanged(me => me.ReportableData.CurrentSprint.AvailableTime).OnChanged(
				me => me.ReportableData.CurrentSprint.TotalTime);
			dependsOn.Call(me => me.OnPropertyChanged("Visibility")).OnChanged(me => me.MonitorViewModel.SprintTitleOrientation);
		}

		public SprintTitleViewModel(IMonitorViewModel monitorViewModel, Orientation placeholderOrientation, IServiceLocator serviceLocator)
			: base(serviceLocator, false)
		{
			this.placeholderOrientation = placeholderOrientation;

			MonitorViewModel = monitorViewModel;
		}

		#region Private Fields

		private readonly Orientation placeholderOrientation;
		private ISprintConfiguration configuration;
		private IMonitorViewModel monitorViewModel;

		#endregion

		#region Private Methods

		private IMonitorViewModel MonitorViewModel
		{
			get { return this.monitorViewModel; }
			set
			{
				if (value != this.monitorViewModel)
				{
					this.monitorViewModel = value;

					OnPropertyChanged("MonitorViewModel");
				}
			}
		}

		private void EnsureConfigurationIsPresent()
		{
			if (this.configuration == null)
			{
				this.configuration = ServiceLocator.GetInstance<ISprintConfiguration>();
			}
		}

		#endregion

		#region ISprintTitleViewModel Members

		public string ProjectName
		{
			get
			{
				GuardDisposed();
				EnsureConfigurationIsPresent();
				return this.configuration.ProjectName;
			}
		}

		public string CurrentSprintName
		{
			get
			{
				GuardDisposed();
				return (CurrentSprint != null ? CurrentSprint.Name : null);
			}
		}

		public double SprintPercentageCovered
		{
			get { return (CurrentSprint != null ? 1.0 - (CurrentSprint.AvailableTime.TotalHours / CurrentSprint.TotalTime.TotalHours) : 0.0); }
		}

		public Visibility Visibility
		{
			get
			{
				GuardDisposed();
				return (this.monitorViewModel.SprintTitleOrientation == PlaceholderOrientation ? Visibility.Visible : Visibility.Collapsed);
			}
		}

		public Orientation PlaceholderOrientation
		{
			get
			{
				GuardDisposed();
				return this.placeholderOrientation;
			}
		}

		#endregion
	}
}